/*对于常量的声明的相关学习
1. 对于constant, 在go中是在编译时候, 就会被创建
2. 只能够是: numbers, characters(runes), strings, 或者boolean类型
3. 对于常量的表达式赋值, 也必须是常量表达式, 例如: 1 << 3; math.Sin(Pi/4)不是, 因为方法的调用是在运行时才能调用
*/
package initialization

import (
	"flag"
	"fmt"
	"log"
	"os"
)

type ByteSize float64

const (
	_           = iota             // ignore first value by assigning to blank identifier
	KB ByteSize = 1 << (10 * iota) // KB的定义
	MB
	GB
	TB
	PB
	EB
	ZB
	YB
)

// 对于变量的配置
var (
	home   = os.Getenv("HOME")
	user   = os.Getenv("USER")
	gopath = os.Getenv("GOPATH")
)

/*
该方法会在variables加载完成之后, 执行该方法, 每个文件中可以拥有多个init方法
*/
func init() {
	// 设置USER选项

	if user == "" {
		// 该方法会在输出日志的时候, 调用退出的方法
		log.Println("${USER} is not set..")
		user = "xianglj"
	}
	if home == "" {
		home = "/home/" + user
	}
}

func init() {
	if gopath == "" {
		gopath = home + "/go"
	}

	// gopath may be overridden by --gopath flag on command line.
	flag.StringVar(&gopath, "gopath", gopath, "override default GOPATH")
}

/**覆盖string方法*/
func (b ByteSize) String() string {
	switch {
	case b >= YB:
		return fmt.Sprintf("%.2fYB", b/YB)
	case b >= ZB:
		return fmt.Sprintf("%.2fZB", b/ZB)
	case b >= EB:
		return fmt.Sprintf("%.2fEB", b/EB)
	case b >= PB:
		return fmt.Sprintf("%.2fPB", b/PB)
	case b >= TB:
		return fmt.Sprintf("%.2fTB", b/TB)
	case b >= GB:
		return fmt.Sprintf("%.2fGB", b/GB)
	case b >= MB:
		return fmt.Sprintf("%.2fMB", b/MB)
	case b >= KB:
		return fmt.Sprintf("%.2fKB", b/KB)
	}
	return fmt.Sprintf("%.2fB", b)
}
